#ifndef __UTILS__
#define __UTILS__

#include <netinet/in.h>

#ifdef DEBUG

#include <assert.h>

#define ASSERT(...) assert(__VA_ARGS__)
//#define DBG(...) printf(__VA_ARGS__)
#define DBG(...) {}
#define ERR(...) fprintf(stderr, ##__VA_ARGS__)
#define IMI_CHECK(__cond, __normal_format, __err_format, ...) if((__cond)) { printf(__normal_format, ##__VA_ARGS__);} else { printf(__err_format, ##__VA_ARGS__);}

#define DUMP_HEX(__label, __data, __len)                                       \
  {                                                                            \
    printf("%s: ", __label);                                                   \
    int __i;                                                                   \
    for (__i = 0; __i < __len; __i++) {                                        \
      printf("%02x", (unsigned char)(((char*)(__data))[__i]));                 \
    }                                                                          \
    printf("\n");                                                              \
  }

#else

#define ASSERT(...) 
#define DBG(...)
#define ERR(...) fprintf(stderr, ##__VA_ARGS__)
#define IMI_CHECK(__cond, __normal_format, __err_format, ...)
#define DUMP_HEX(__label, __data, __len)

#endif

//typedef int BOOL;

#ifndef    FALSE
#define    FALSE    (0)
#endif

#ifndef    TRUE
#define    TRUE    (!FALSE)
#endif

#define TRUE_STR  "true"
#define FALSE_STR "false"

// min，max
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif // !MAX

#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif // !MIN

#define BYTE_TO_SHORT_VALUE(x) ((unsigned short)ntohs((x)))
//#define BYTE_TO_SHORT_VALUE(x) ((unsigned short)(x >> 8 | x << 8))

typedef struct memoryStream *memoryStream_t;

memoryStream_t createStreamFromFile(const char *filePath);

memoryStream_t createStreamFromBytes(char *bytes, int length);

int saveStreamToFile(const char *filePath, memoryStream_t stream);

void releaseStream(memoryStream_t stream);

int readStream(char* out, int readSize, memoryStream_t stream);

int writeStream(char* buffer, int writeSize, memoryStream_t stream);

int seekStream(memoryStream_t stream, int offset);

int getStreamPos(memoryStream_t stream);

void setStreamPos(memoryStream_t stream, int pos);

int getStreamSize(memoryStream_t stream);

int peekStream(char *buffer, int peekSize, int offset, memoryStream_t stream);

//-----------------------------------------------------------------------
// @brief      读取指定文件的所有内容并返回给调用者。
// @path       需要读入的文件路径
// @out_size   输出的缓冲区大小
// @return     读入的文件缓冲区。调用者需要自己释放
//-----------------------------------------------------------------------
char* read_all_data_new(const char *path, int* out_size);

//-----------------------------------------------------------------------
// @brief      从指定字符串的开始位置，读取指定分隔符前的字符串作为token，
//             复制到指定的缓冲区当中。例如"hello, world", delimeter=", "
//             则缓冲区填入"hello", 返回指针指向" world"。中间连续多个分
//             隔符会自动被跳过，不输出任何token. 例如"::a:b:,:c",分割符
//             为":,"时，连续调用时会输出a, b, c
// @ptrSrc     [in/out]需要处理的字符串. 函数返回时，ptrSrc指向处理到位置
// @out        输出的缓冲区
// @maxOut     缓冲区的长度
// @delimeters 分隔符数组. 例如{','}
// @len        分隔符数组长度
// @return     输出的token长度(不包括\0). 小于0表示串已经结束或者遇到错误
//-----------------------------------------------------------------------
int imi_str_read_token(char** ptrSrc, char* out, int maxOut, const char *delimeters, int len);

#endif // __UTILS__
